﻿using System;
using System.Collections.Generic;

using Gdk;
using Gtk;
using Cairo;

using Google.Protobuf;
using Google.Protobuf.Examples.AddressBook;

namespace testClient
{
	public class DrawGraph : DrawingArea
	{

		public World world;
		public DrawGraph()
		{

		}

		public static void DrawCircle(Context gr, float x, float y, float radius)
		{
			gr.Save();
			gr.MoveTo(x + radius, y);
			gr.Arc(x, y, radius, 0, 360);
			gr.Restore();
		}

		private void DrawBody(Body b, Context gr)
		{
			DrawCircle(gr, b.x, b.y, 10);
		}

		public static Gdk.Pixbuf GetCircle()
		{
			var imgSurface = new Cairo.ImageSurface(Format.ARGB32, 20, 20);
			var context = new Cairo.Context(imgSurface);

			//var buf = new byte[4 * 20 * 20];

			//var pixBuf = new Gdk.Pixbuf("test.png");

			//Gdk.CairoHelper.SetSourcePixbuf(context, pixBuf, 0, 0);

			DrawCircle(context, 10, 10, 10);
			var g = context;
			g.Color = new Cairo.Color(0, 0, 1, 1);
			g.LineWidth = 2;
			g.Stroke();
			g.Save();
			g.Dispose();

			imgSurface.WriteToPng("test.png");
			//imgSurface.

			//Cairo 的数据存储格式
			//RGBA
			//gui库的数据存储方式
			//BGRA
			// 1, 0.2, 0.8, 1  RGB 
			var data = imgSurface.Data;
			for (var i = 0; i < data.Length; i += 4)
			{
				var temp = data[i];
				data[i] = data[i + 2];
				data[i + 2] = temp;
			}
			var pixBuf = new Gdk.Pixbuf(data, Colorspace.Rgb, true, 8, 20, 20, 20 * 4, null);

			return pixBuf;
		}

		protected override bool OnExposeEvent(EventExpose evnt)
		{

			return true;
		}
	}


	public class Body
	{
		public float x, y;
		public Gtk.Image image;
	}

	public class World
	{
		public static World world;

		public List<Body> body = new List<Body>()
		{
			new Body(){x=100, y=100},
			new Body(){x=20, y=20},
		};


		public GameControl gameControl;
		private Gtk.Window window;
		public Gtk.Fixed fixedContainer;

		//500 * 500
		public void Render(float w, float h)
		{
			world = this;

			Application.Init();
			Gtk.Window window = new Gtk.Window("Test");
			this.window = window;
			//var a = new DrawGraph();
			//a.world = this;
			//var box = new HBox();
			//box.Add(a);

			var fix = new Gtk.Fixed();
			fixedContainer = fix;
			window.Add(fix);

			//window.Add(box);

			window.SetDefaultSize((int)w, (int)(h));

			var pb1 = DrawGraph.GetCircle();
			var image1 = new Gtk.Image(pb1);
			fix.Put(image1, 100, 100);
			body[0].image = image1;

			var image2 = new Gtk.Image(pb1);
			fix.Put(image2, 20, 20);
			body[1].image = image2;



			window.ShowAll();
			GLib.Timeout.Add(30, new GLib.TimeoutHandler(Forever));
			GLib.Timeout.Add(100, new GLib.TimeoutHandler(Sync));

			Application.Run();
		}
		public static int playerId = 2;
		bool Sync()
		{
			MainClass.udpClient.Send(new string[] { "s", "pos", ((int)body[0].x).ToString(), ((int)body[0].y).ToString() });
			return true;
		}

		private int lastFrameId = 0;
		public void SyncBody(IMessage msgData)
		{
			var proto = msgData as MovePosC2S;
			if (proto.Id != playerId)
			{
				var frameId = proto.FrameId;
				//lastFrameId < frameId && diff < 128 
				//lastFrameId > frameId :  frameId - lastFrameId + 256 < 128
				var diff = frameId - lastFrameId;
				if (lastFrameId < frameId && diff < 128)
				{
					lastFrameId = frameId;
					body[1].x = proto.X;
					body[1].y = proto.Y;
				}
				else if (lastFrameId > frameId && (diff + 256) < 128)
				{
					lastFrameId = frameId;
					body[1].x = proto.X;
					body[1].y = proto.Y;
				}

			}
		}

		bool Forever()
		{
			//this.gameControl.Run();
			this.gameControl.UpdateBody();
			fixedContainer.Move(body[0].image, (int)body[0].x, (int)body[0].y);
			fixedContainer.Move(body[1].image, (int)body[1].x, (int)body[1].y);
			this.window.QueueDraw();
			return true;
		}

		public Body GetMyBody()
		{
			return body[0];
		}
	}
}

